#include "stdafx.h"
#include "ApproachHolder.h"
#include "GridParam.h"
#include "SimpleFile.h"
#include "EphemWrapper.h"

CApproachHolder::CApproachHolder(void)
: m_pDrawInterface(NULL)
{
	{
		using namespace boost::posix_time;
		m_startTime = to_tm(second_clock::local_time());
	}
}

CApproachHolder::~CApproachHolder(void)
{
	ListPtrApproachs listAppPtrs;

	MapTraceApproaches::const_iterator itTrace = m_mapTraceApproaches.begin();
	MapTraceApproaches::const_iterator endTrace = m_mapTraceApproaches.end();
	for(; itTrace != endTrace; ++itTrace)
	{
		const CApproachTrace::Ptr pTraceApproach = itTrace->second;
		pTraceApproach->GetApproachesList(listAppPtrs);
	}


	CStdString filename;
	filename.Format("Result_%04d-%02d-%02d_%02d-%02d-%02d.txt", m_startTime.tm_year + 1900, m_startTime.tm_mon+1, m_startTime.tm_mday, m_startTime.tm_hour, m_startTime.tm_min, m_startTime.tm_sec); 
	CSimpleFile outFile(filename, "w+");

	double timeDif = 10.0;
	double prevTime = 0.0;
	listAppPtrs.sort(CApproach::CompareApproachesByTimeParam);
	ListPtrApproachs::const_iterator itList = listAppPtrs.begin();
	ListPtrApproachs::const_iterator endList = listAppPtrs.end();
	for(; itList != endList; ++itList)
	{
		const CApproach::Ptr app = *itList;
		if( (prevTime != 0.0) && (app->m_dTime - prevTime > timeDif) )
			fprintf(outFile, "\n");
		prevTime = app->m_dTime;

		fprintf(outFile, "%15.7lf %s | %15.11lf %15.4f | %10.16lf | %8s | %+15.4lf %+15.4lf %+15.4lf\n",
			app->m_dTime, (LPCTSTR)CEphemWrapper::StrDateFromJD(app->m_dTime), 
			app->m_dDist, CEphemWrapper::AUtoKM(app->m_dDist),
			app->m_pAsteroidOrbitParam->GetVariousParam(), CEphemWrapper::GetBodyName(app->m_bodyNum),
			CEphemWrapper::AUtoKM(app->m_dXdiff[0]), CEphemWrapper::AUtoKM(app->m_dXdiff[1]), CEphemWrapper::AUtoKM(app->m_dXdiff[2]));
	}
}

bool CApproachHolder::AppendDrawInterface(IDrawInterface *pDrawInterface)
{
	m_pDrawInterface = pDrawInterface;
	return true;
}

bool CApproachHolder::AppendTraceApproaches(CApproachTrace::Ptr listApprc)
{
	if(m_pDrawInterface)
	{
		ListPtrApproachs listPtrApproaches;
		listApprc->GetApproachesList(listPtrApproaches);
		m_pDrawInterface->AppendApproaches(listPtrApproaches);
	}

	boost::mutex::scoped_lock acs(m_mtxMap);
	const CAsteroidOrbitParam::Ptr pAsteroidOrbitParam = listApprc->GetAsteroidOrbitParam();
	if(m_mapTraceApproaches.count(pAsteroidOrbitParam) == 0)
	{
		m_mapTraceApproaches[pAsteroidOrbitParam] = listApprc;
	}
	else
	{
		CApproachTrace::Ptr pCurrentList = m_mapTraceApproaches[pAsteroidOrbitParam];
		pCurrentList->Merge(listApprc);
	}
	return true;
}

bool CApproachHolder::GetApproachesInRange(const CGridParam &ranges, ListPtrApproachs &ListOut)
{
	ListOut.clear();
	boost::mutex::scoped_lock acs(m_mtxMap);
	MapTraceApproaches::iterator itTrace = m_mapTraceApproaches.begin();
	MapTraceApproaches::iterator endTrace = m_mapTraceApproaches.end();
	for(; itTrace != endTrace; ++itTrace)
	{
		if(!ranges.IsIncludedRange(itTrace->first->GetVariousParam()))
			continue;

		const CApproachTrace::Ptr pTraceApproach = itTrace->second;
		pTraceApproach->GetApproachesList(ranges, ListOut);
	}
	return true;
}
